Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement node runtime region awareness for cdk vended custom resources #30108

Merged
merged 22 commits into from
Jun 11, 2024

Conversation

colifran
Copy link
Contributor

@colifran colifran commented May 8, 2024

Reason for this change

This PR introduces node runtime region awareness into the custom resource provider framework by doing the following:

  • Adding a LATEST_NODE_RUNTIME_MAP fact table used to maintain the latest node runtime available per AWS partition
  • Introducing determineLatestNodeRuntime and determineLatestNodeRuntimeName functions which determine the latest Lambda node Runtime and the latest Lambda node Runtime name, respectively
  • Updating the custom resource provider framework to utilize these two functions when code generating the runtime property for providers using node runtimes

Description of changes

This PR can be segmented into the following code changes:

  • A LATEST_NODE_RUNTIME_MAP fact table was added which maintains the latest Lambda node runtime available per AWS partition.
  • Introduced determineLatestNodeRuntime and determineLatestNodeRuntimeName functions which determine the latest Lambda node Runtime and the latest Lambda node Runtime name, respectively.
  • The existing runtime property being code generated via the custom resource provider framework has been altered to now use the appropriate runtime determiner function, i.e., determineLatestNodeRuntimeName for CustomResourceProvider or determineLatestNodeRuntime for Function or SingletonFunction. Any custom resource provider using a python runtime will not use either of these functions.
  • To consolidate and manage importing of external modules a ModuleImporter class has been created. This class allows external modules to be registered as an import for a target module and prevents duplicate imports for modules that contain multiple framework components. This class also provides the ability to specify different import paths which allows all external modules to be consolidated into a single class rather than having duplicate external modules defined for different import paths. Lastly, this class determines whether or not external modules should be imported selectively or if all targets in the external module should be imported under an alias, i.e., import { Function } from 'aws-lambda' vs. import * as lambda from 'aws-lambda'
  • A CallableExpr class was created to allow expression proxies to be created from a specified expression name. This allows the new runtime determiner functions and other module specific functions to be called from their specified module and built into a JavaScript object that will mirror the JavaScript operations done to it in an expression tree.

Description of how you validated changes

Manually tested all individual custom resource handlers for create, update, and delete. I verified that the behavior seen was what was expected based off of the handler code. All impacted integ tests were updated. New unit tests were added to the custom resource handler framework to test that generated code correctly included determineLatestNodeRuntime for Lambda based handlers and determineLatestNodeRuntimeName for CfnResource based handlers. Added new unit tests to test the functionality of determineLatestNodeRuntime and determineLatestNodeRuntimeName for region agnostic stacks, stacks in commercial region, stacks in China regions, stacks in ADC regions, and stacks in GovCloud regions.

Checklist


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@aws-cdk-automation aws-cdk-automation requested a review from a team May 8, 2024 17:34
@github-actions github-actions bot added the p2 label May 8, 2024
@mergify mergify bot added the contribution/core This is a PR that came from AWS. label May 8, 2024
@colifran colifran self-assigned this May 8, 2024
@colifran colifran changed the title feat: implement region awareness for node runtimes into custom resource framework feat: implement region awareness for node runtimes into custom resource provider framework May 8, 2024
Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pull request linter has failed. See the aws-cdk-automation comment below for failure reasons. If you believe this pull request should receive an exemption, please comment and provide a justification.

A comment requesting an exemption should contain the text Exemption Request. Additionally, if clarification is needed add Clarification Request to a comment.

Comment on lines -218 to -240
type: scope.coreInternal
? CORE_INTERNAL_CR_PROVIDER.CustomResourceProviderOptions
: CORE_MODULE.CustomResourceProviderOptions,
Copy link
Contributor Author

@colifran colifran May 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one example of what the ModuleImporter class helps with. We can maintain one module, e.g., CORE_MODULE, defined with all of it's types, expressions, etc. rather than needing to define a duplicate module just based on where the module would be imported from, i.e. core vs. aws-lambda. Instead, when registering an import we can just register the same module with a different fromLocation specified. Now the code looks a lot cleaner and we maintain a single module definition.

Comment on lines -274 to -341
/**
* External modules that this class depends on.
*/
protected abstract readonly externalModules: ExternalModule[];

private importExternalModulesInto(scope: HandlerFrameworkModule) {
for (const module of this.externalModules) {
if (!scope.hasExternalModule(module)) {
scope.addExternalModule(module);
this.importExternalModuleInto(scope, module);
}
}
}

private importExternalModuleInto(scope: HandlerFrameworkModule, module: ExternalModule) {
switch (module.fqn) {
case PATH_MODULE.fqn: {
PATH_MODULE.import(scope, 'path');
return;
}
case CONSTRUCTS_MODULE.fqn: {
CONSTRUCTS_MODULE.importSelective(scope, ['Construct']);
return;
}
case CORE_MODULE.fqn: {
CORE_MODULE.importSelective(scope, [
'Stack',
'CustomResourceProviderBase',
'CustomResourceProviderOptions',
]);
return;
}
case CORE_INTERNAL_CR_PROVIDER.fqn: {
CORE_INTERNAL_CR_PROVIDER.importSelective(scope, [
'CustomResourceProviderBase',
'CustomResourceProviderOptions',
]);
return;
}
case CORE_INTERNAL_STACK.fqn: {
CORE_INTERNAL_STACK.importSelective(scope, ['Stack']);
return;
}
case LAMBDA_MODULE.fqn: {
LAMBDA_MODULE.import(scope, 'lambda');
return;
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of reduced code here due to ModuleImporter class managing imports

Copy link
Contributor

@rix0rrr rix0rrr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overall name of the framework was changed from HandlerFramework to ProviderFramework. This is because the framework is being used to code generate custom resource providers. The custom resource providers execute handler code that this framework has the responsibility of bundling, but calling this a HandlerFramework isn't accurate.

Not in fact true, as far as I'm aware. We call it "custom resource handlers" etc, but I'm pretty sure it also contains Lambda Handlers that don't go into custom resources. Yes, 90% of them are custom resources, but not 100%. So calling this all "custom resources" is a mental shortcut.

/**
* The latest Lambda NodeJS runtime available in a given region.
*/
public static readonly LATEST_NODE_RUNTIME = 'latestNodeRuntime';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also would expect this version to be used for lambda.Runtime.LATEST_NODEJS

Copy link
Contributor

@MrArnoldPalmer MrArnoldPalmer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lot's of good improvements to the codegen here that makes it more robust. I'll leave others to approve but I think this handles the move back to a "deploy time" computed runtime value well. 👍🏻

@bergjaak bergjaak removed their assignment May 21, 2024
@colifran colifran changed the title feat: implement region awareness for node runtimes into custom resource provider framework feat: implement region awareness for node runtimes for cdk vended custom resources May 23, 2024
@colifran colifran added the pr/do-not-merge This PR should not be merged at this time. label May 28, 2024
@colifran colifran marked this pull request as ready for review May 28, 2024 15:08
@aws-cdk-automation aws-cdk-automation dismissed their stale review May 28, 2024 15:10

✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.

@colifran colifran changed the title feat: implement region awareness for node runtimes for cdk vended custom resources feat: implement node runtime region awareness for cdk vended custom resources May 28, 2024
@aws-cdk-automation aws-cdk-automation added the pr/needs-maintainer-review This PR needs a review from a Core Team Member label May 28, 2024
Copy link
Contributor

@scanlonp scanlonp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, would like to go over it with you in more depth. Only small thing I noticed is we should add isVariable: true to the runtime created by the determineLatestNodeRuntime() function in runtime.ts.

@TheRealAmazonKendra TheRealAmazonKendra force-pushed the colifran/region-aware-framework branch 2 times, most recently from 8305b3a to 73379cf Compare June 6, 2024 02:06
Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The pull request linter has failed. See the aws-cdk-automation comment below for failure reasons. If you believe this pull request should receive an exemption, please comment and provide a justification.

A comment requesting an exemption should contain the text Exemption Request. Additionally, if clarification is needed add Clarification Request to a comment.

Signed-off-by: Francis <colifran@amazon.com>
Signed-off-by: Francis <colifran@amazon.com>
@aws-cdk-automation aws-cdk-automation dismissed their stale review June 6, 2024 02:38

✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.

Signed-off-by: Francis <colifran@amazon.com>
Signed-off-by: Francis <colifran@amazon.com>
Signed-off-by: Francis <colifran@amazon.com>
Signed-off-by: Francis <colifran@amazon.com>
@aws-cdk-automation aws-cdk-automation removed the pr/needs-maintainer-review This PR needs a review from a Core Team Member label Jun 11, 2024
@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: 50eaec9
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

Copy link
Contributor

mergify bot commented Jun 11, 2024

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify mergify bot merged commit 69c5dde into main Jun 11, 2024
13 checks passed
@mergify mergify bot deleted the colifran/region-aware-framework branch June 11, 2024 18:59
amazon-codecatalyst bot pushed a commit to pahud/aws-cdk that referenced this pull request Jun 12, 2024
…esources (aws#30108)

This PR introduces node runtime region awareness into the custom resource provider framework by doing the following:

- Adding a `LATEST_NODE_RUNTIME_MAP` fact table used to maintain the latest node runtime available per AWS partition
- Introducing `determineLatestNodeRuntime` and `determineLatestNodeRuntimeName` functions which determine the latest Lambda node `Runtime` and the latest Lambda node `Runtime` name, respectively
- Updating the custom resource provider framework to utilize these two functions when code generating the runtime property for providers using node runtimes

This PR can be segmented into the following code changes:

- A `LATEST_NODE_RUNTIME_MAP` fact table was added which maintains the latest Lambda node runtime available per AWS partition.
- Introduced `determineLatestNodeRuntime` and `determineLatestNodeRuntimeName` functions which determine the latest Lambda node `Runtime` and the latest Lambda node `Runtime` name, respectively.
- The existing runtime property being code generated via the custom resource provider framework has been altered to now use the appropriate runtime determiner function, i.e., `determineLatestNodeRuntimeName` for `CustomResourceProvider` or `determineLatestNodeRuntime` for `Function` or `SingletonFunction`. Any custom resource provider using a python runtime will not use either of these functions.
- To consolidate and manage importing of external modules a `ModuleImporter` class has been created. This class allows external modules to be registered as an import for a target module and prevents duplicate imports for modules that contain multiple framework components. This class also provides the ability to specify different import paths which allows all external modules to be consolidated into a single class rather than having duplicate external modules defined for different import paths. Lastly, this class determines whether or not external modules should be imported selectively or if all targets in the external module should be imported under an alias, i.e., `import { Function } from 'aws-lambda'` vs. `import * as lambda from 'aws-lambda'`
- A `CallableExpr` class was created to allow expression proxies to be created from a specified expression name. This allows the new runtime determiner functions and other module specific functions to be called from their specified module and built into a JavaScript object that will mirror the JavaScript operations done to it in an expression tree.

Manually tested all individual custom resource handlers for create, update, and delete. I verified that the behavior seen was what was expected based off of the handler code. All impacted integ tests were updated. New unit tests were added to the custom resource handler framework to test that generated code correctly included `determineLatestNodeRuntime` for Lambda based handlers and `determineLatestNodeRuntimeName` for `CfnResource` based handlers. Added new unit tests to test the functionality of `determineLatestNodeRuntime` and `determineLatestNodeRuntimeName` for region agnostic stacks, stacks in commercial region, stacks in China regions, stacks in ADC regions, and stacks in GovCloud regions.

- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
mazyu36 pushed a commit to mazyu36/aws-cdk that referenced this pull request Jun 22, 2024
…esources (aws#30108)

### Reason for this change

This PR introduces node runtime region awareness into the custom resource provider framework by doing the following:

- Adding a `LATEST_NODE_RUNTIME_MAP` fact table used to maintain the latest node runtime available per AWS partition
- Introducing `determineLatestNodeRuntime` and `determineLatestNodeRuntimeName` functions which determine the latest Lambda node `Runtime` and the latest Lambda node `Runtime` name, respectively
- Updating the custom resource provider framework to utilize these two functions when code generating the runtime property for providers using node runtimes

### Description of changes

This PR can be segmented into the following code changes:

- A `LATEST_NODE_RUNTIME_MAP` fact table was added which maintains the latest Lambda node runtime available per AWS partition.
- Introduced `determineLatestNodeRuntime` and `determineLatestNodeRuntimeName` functions which determine the latest Lambda node `Runtime` and the latest Lambda node `Runtime` name, respectively.
- The existing runtime property being code generated via the custom resource provider framework has been altered to now use the appropriate runtime determiner function, i.e., `determineLatestNodeRuntimeName` for `CustomResourceProvider` or `determineLatestNodeRuntime` for `Function` or `SingletonFunction`. Any custom resource provider using a python runtime will not use either of these functions.
- To consolidate and manage importing of external modules a `ModuleImporter` class has been created. This class allows external modules to be registered as an import for a target module and prevents duplicate imports for modules that contain multiple framework components. This class also provides the ability to specify different import paths which allows all external modules to be consolidated into a single class rather than having duplicate external modules defined for different import paths. Lastly, this class determines whether or not external modules should be imported selectively or if all targets in the external module should be imported under an alias, i.e., `import { Function } from 'aws-lambda'` vs. `import * as lambda from 'aws-lambda'`
- A `CallableExpr` class was created to allow expression proxies to be created from a specified expression name. This allows the new runtime determiner functions and other module specific functions to be called from their specified module and built into a JavaScript object that will mirror the JavaScript operations done to it in an expression tree.

### Description of how you validated changes

Manually tested all individual custom resource handlers for create, update, and delete. I verified that the behavior seen was what was expected based off of the handler code. All impacted integ tests were updated. New unit tests were added to the custom resource handler framework to test that generated code correctly included `determineLatestNodeRuntime` for Lambda based handlers and `determineLatestNodeRuntimeName` for `CfnResource` based handlers. Added new unit tests to test the functionality of `determineLatestNodeRuntime` and `determineLatestNodeRuntimeName` for region agnostic stacks, stacks in commercial region, stacks in China regions, stacks in ADC regions, and stacks in GovCloud regions.

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@aws-cdk-automation
Copy link
Collaborator

Comments on closed issues and PRs are hard for our team to see. If you need help, please open a new issue that references this one.

@aws aws locked as resolved and limited conversation to collaborators Jul 25, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
contribution/core This is a PR that came from AWS. p2
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants